package com.gulimall.authserver.controller.web;

import com.alibaba.fastjson.TypeReference;
import com.guigui.common.constant.SmsConstant;
import com.guigui.common.utils.R;
import com.gulimall.authserver.dto.LoginDto;
import com.guigui.common.to.MemberDto;
import com.gulimall.authserver.dto.RegisterDto;
import com.gulimall.authserver.feign.MemberFeignServices;
import com.gulimall.authserver.feign.ThirdPartSmsFeignServices;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Controller
public class RegisterController {

    @Autowired
    private ThirdPartSmsFeignServices thirdPartSmsFeignServices;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private MemberFeignServices memberFeignServices;

    @GetMapping("/sms/send")
    @ResponseBody
    public R sendSmsCode(@RequestParam("phone") String phone) {
        String key = SmsConstant.REDIS_SMS_PREFIX + "_" + phone;
        String code = redisTemplate.opsForValue().get(key);
        if (!StringUtils.isNullOrEmpty(code)) {
            String[] split = code.split("_");
            long sendTime = Long.parseLong(split[1]);
            if (System.currentTimeMillis() - sendTime < 60 * 1000 * 2) {
                return R.error("间隔太快啦，请稍后再试");
            }
        }
        code = UUID.randomUUID().toString().substring(0, 4);
        thirdPartSmsFeignServices.sendSmsCode(phone, code);
        code = code + "_" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(key, code, 10, TimeUnit.MINUTES);
        return R.ok();
    }

    @PostMapping("/register")
    public String register(@Valid RegisterDto registerDto, BindingResult dtoResult, RedirectAttributes redirectAttributes) {

        if (dtoResult.hasErrors()) {
            Map<String, String> errors = dtoResult.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors", errors);
        } else {
            String code = registerDto.getCode();
            String key = SmsConstant.REDIS_SMS_PREFIX + "_" + registerDto.getPhone();
            String val = redisTemplate.opsForValue().get(key);
            if (!StringUtils.isNullOrEmpty(val) && val.split("_")[0].equals(code)) {
                R register = memberFeignServices.register(registerDto);
                if (register.getCode() == 0) {
                    redisTemplate.delete(key);
                    return "redirect:http://gulimall.com";
                }
                String msg = register.getData("msg", new TypeReference<String>() {});
                Map<String, String> error = new HashMap<>(1);
                error.put("error", msg);
                redirectAttributes.addFlashAttribute("error" ,error);
            }
        }

        return "redirect:http://auth.gulimall.com/reg";
    }

    @PostMapping("/login")
    public String login(@Valid LoginDto loginDto, BindingResult result, RedirectAttributes redirectAttributes, HttpServletRequest request) {
        R login = memberFeignServices.login(loginDto);
        if (login.getCode() == 0) {
            MemberDto member = login.getData(new TypeReference<MemberDto>() {});
            HttpSession session = request.getSession();
            session.setAttribute("user", member);
            return "redirect:http://gulimall.com";
        }

        String msg = login.getData("msg", new TypeReference<String>() {});
        Map<String, String> error = new HashMap<>(1);
        error.put("error", msg);
        redirectAttributes.addFlashAttribute("error", error);
        return "redirect:http://auth.gulimall.com/reg";
    }
}
